/*
* Copyright (C) [2020] Futurewei Technologies, Inc. All rights reverved.
*
* OpenArkFE is licensed under the Mulan PSL v1.
* You can use this software according to the terms and conditions of the Mulan PSL v1.
* You may obtain a copy of Mulan PSL v1 at:
*
*  http://license.coscl.org.cn/MulanPSL
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR
* FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v1 for more details.
*/

///////////////////////////////////////////////////////////////////////////////
// The type in AST doesn't have any physical representation. It's merely for
// syntax validation and potential optimizations for future R&D project.
//
// Each language should define its own type system, and its own validation rules.
// We only define two categories of types in this file, Primitive and User types.
//
//
//                    About the User Type
//
// The user type could come from class, struct, interface, ...
// To accomodate the above multiple cases, we simply put TreeNode*
// as the type info. And there are some issues.
// (1) During parsing, each instance of identifier is given a new tree node,
//     and multiple instance of a same user type are treated as different types.
// (2) Of course, situation in (1) is wrong, we need consolidate all these
//     instance into one single same type. This has to be done when the tree
//     is done creation.
// (3) To consolidate the multiple instances of a type symbol, the scope
//     info has to kick in. This is another issue.
// Right now, I just let each instance represent a separate type, and will
// come back to this.
//
// So we a TreeNode of the type identifier can be a type, and we don't have
// to give any special data struct for it. A user type is created as a treenode
// (IdentifierNode) at the beginning, but later we will do consolidation,
// and it may be turned into a function, struct, etc. So a TreeNode is good here.
//
// So, we only need to handle the primitive types which are coming
// from language keywords.  This file handles the primitive types.
//////////////////////////////////////////////////////////////////////////

#ifndef __AST_TYPE_H__
#define __AST_TYPE_H__

#include "ruletable.h"
#include "mempool.h"
#include "ast.h"
#include "ast_mempool.h"

class PrimTypeNode : public TreeNode {
private:
  TypeId    mPrimType; // primitive type
public:
  PrimTypeNode() {mKind = NK_PrimType;}
  ~PrimTypeNode(){}

  TypeId    GetPrimType()     {return mPrimType;}
  void SetPrimType(TypeId id) {mPrimType = id; }
  const char* GetName();  // type name

  void Dump(unsigned);
};

///////////////////////////////////////////////////////////////////////////////
//                          PrimTypePool
// The size of PrimTypeNode is fixed, so it's good to use container for the storage.
// The PrimTypeNode pool is global, across all modules.
///////////////////////////////////////////////////////////////////////////////

class PrimTypePool {
private:
  TreePool                   mTreePool;
  SmallVector<PrimTypeNode*> mTypes;

  void Init();

public:
  PrimTypePool();
  ~PrimTypePool();

  PrimTypeNode* FindType(const char *keyword);
  PrimTypeNode* FindType(TypeId id);
};

// A global pool for Primitive TypeNodes.
extern PrimTypePool gPrimTypePool;

#endif
